/**
 * Copyright (C) 2010  ARToolkitPlus Authors
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *  Thomas Pintaric
 *  Pavel Rojtberg
 */

#ifndef __BCH_CODE__H__
#define __BCH_CODE__H__

#include <vector>

namespace ARToolKitPlus {

// --------------------------------------------------------
// WARNING: It is *NOT SAFE* to alter the values below!

#define BCH_DEFAULT_M       6
#define BCH_DEFAULT_LENGTH 36
#define BCH_DEFAULT_T       4
#define BCH_DEFAULT_K      12

#define BCH_MAX_M    6
#define BCH_MAX_P    7  // MAX_M+1
#define BCH_MAX_LUT 64  // 2^MAX_M
#define BCH_MAX_SQ   8  // SQRT(MAX_LUT) -- (?)
// -------------------------------------------------------

// we only use unsigned __int64 under windows.
// have to use unsigned long long othersie...
#if defined(_MSC_VER) || defined(_WIN32_WCE)
typedef unsigned __int64 _64bits;
#else
typedef unsigned long long _64bits;
#endif

//static bool _isBitSet(_64bits bn, int which_bit);
//static void _setBit(_64bits &bn, int which_bit);
/*
 static void _clearBit(_64bits &bn, int which_bit);
 static void _copyBit(_64bits &dest_n, const int dest_bit, const _64bits src_n, const int src_bit);
 static int _countOnes(const _64bits src_n);
 */

//static int* toBitPattern(int b[], _64bits n, int n_bits);
//static _64bits fromBitPattern(int b[], int n_bits);

// static void printBitPattern(_64bits n, int n_bits);


class BCH
// this class implements a (36, 12, 9) binary BCH encoder/decoder
{
public:
    BCH();

    void encode(int encoded_bits[BCH_DEFAULT_LENGTH], const _64bits orig_n);
    bool decode(int &err_n, _64bits &orig_n, const int encoded_bits[BCH_DEFAULT_LENGTH]);

    void encode(_64bits &encoded_n, const _64bits orig_n);
    bool decode(int &err_n, _64bits &orig_n, const _64bits encoded_n);

protected:
    BCH(int _m, int _length, int _t);
    void initialize(int _m, int _length, int _t);
    void generate_gf();
    bool gen_poly(int _t);
    void encode_bch(int *bb, const int *data); // int bb[length - k], data[k]
    int decode_bch(int *recd);

    int t;
    int m, n, length, k, d;

    std::vector<int> p;
    std::vector<int> alpha_to;
    std::vector<int> index_of;
    std::vector<int> g;

    std::vector<std::vector<int> > _elp;
    std::vector<int> _d;
    std::vector<int> _l;
    std::vector<int> _u_lu;
    std::vector<int> _s;
    std::vector<int> _root;
    std::vector<int> _loc;
    std::vector<int> _reg;
};

} // namespace ARToolKitPlus


#endif // __BCH_CODE__H__
